package diagram

import 

// Config holds configuration for diagram rendering.
// This replaces global variables and makes the rendering functions testable and thread-safe.
type Config struct {
	// UseAscii determines whether to use ASCII characters (true) or Unicode box-drawing characters (false)
	UseAscii bool

	// ShowCoords displays coordinate debugging information (for development)
	ShowCoords bool

	// Verbose enables detailed logging
	Verbose bool

	// --- Graph-specific configuration ---

	// BoxBorderPadding is the padding between text and border in graph nodes
	BoxBorderPadding int

	// PaddingBetweenX is the horizontal space between nodes in graphs
	PaddingBetweenX int

	// PaddingBetweenY is the vertical space between nodes in graphs
	PaddingBetweenY int

	// GraphDirection is the direction of graph layout ("LR" or "TD")
	GraphDirection string

	// StyleType determines output format for graph diagrams ("cli" or "html")
	// This controls whether graphs use colored output (html) or plain text (cli)
	StyleType string

	// --- Sequence diagram-specific configuration ---

	// SequenceParticipantSpacing is the horizontal space between participants
	SequenceParticipantSpacing int

	// SequenceMessageSpacing is the vertical space between messages (lifeline segments)
	SequenceMessageSpacing int

	// SequenceSelfMessageWidth is the width of self-message loops
	SequenceSelfMessageWidth int
}

// DefaultConfig returns a Config with sensible defaults.
// The returned config is guaranteed to pass validation.
func () *Config {
	return &Config{
		UseAscii:   false, // Use Unicode by default for better appearance
		ShowCoords: false,
		Verbose:    false,
		// Graph defaults
		BoxBorderPadding: 1,
		PaddingBetweenX:  5,
		PaddingBetweenY:  5,
		GraphDirection:   "LR",
		StyleType:        "cli",
		// Sequence diagram defaults
		SequenceParticipantSpacing: 5,
		SequenceMessageSpacing:     1,
		SequenceSelfMessageWidth:   4,
	}
}

// NewConfig creates a new Config with the provided values and validates them.
// Returns an error if any values are invalid.
// For default values, use DefaultConfig() instead.
func ( bool, ,  string) (*Config, error) {
	 := &Config{
		UseAscii:                   ,
		ShowCoords:                 false,
		Verbose:                    false,
		BoxBorderPadding:           1,
		PaddingBetweenX:            5,
		PaddingBetweenY:            5,
		GraphDirection:             ,
		StyleType:                  ,
		SequenceParticipantSpacing: 5,
		SequenceMessageSpacing:     1,
		SequenceSelfMessageWidth:   4,
	}

	if  := .Validate();  != nil {
		return nil, 
	}

	return , nil
}

func (, ,  bool, , ,  int,  string) (*Config, error) {
	 := DefaultConfig()
	 := &Config{
		UseAscii:                   ,
		ShowCoords:                 ,
		Verbose:                    ,
		BoxBorderPadding:           ,
		PaddingBetweenX:            ,
		PaddingBetweenY:            ,
		GraphDirection:             ,
		StyleType:                  "cli",
		SequenceParticipantSpacing: .SequenceParticipantSpacing,
		SequenceMessageSpacing:     .SequenceMessageSpacing,
		SequenceSelfMessageWidth:   .SequenceSelfMessageWidth,
	}

	if  := .Validate();  != nil {
		return nil, 
	}

	return , nil
}

func ( bool, , ,  int) (*Config, error) {
	 := DefaultConfig()
	 := &Config{
		UseAscii:                   ,
		ShowCoords:                 false,
		Verbose:                    false,
		BoxBorderPadding:           ,
		PaddingBetweenX:            ,
		PaddingBetweenY:            ,
		GraphDirection:             "LR",
		StyleType:                  "html",
		SequenceParticipantSpacing: .SequenceParticipantSpacing,
		SequenceMessageSpacing:     .SequenceMessageSpacing,
		SequenceSelfMessageWidth:   .SequenceSelfMessageWidth,
	}

	if  := .Validate();  != nil {
		return nil, 
	}

	return , nil
}

// NewTestConfig creates a Config for testing with sensible defaults.
// The styleType parameter determines output format ("cli" or "html").
func ( bool,  string) *Config {
	 := DefaultConfig()
	.UseAscii = 
	.StyleType = 
	return 
}

// Validate checks if the configuration values are valid.
// Returns an error if any values are invalid or would cause rendering issues.
func ( *Config) () error {
	// Validate graph configuration
	if .BoxBorderPadding < 0 {
		return &ConfigError{Field: "BoxBorderPadding", Value: .BoxBorderPadding, Message: "must be non-negative"}
	}
	if .PaddingBetweenX < 0 {
		return &ConfigError{Field: "PaddingBetweenX", Value: .PaddingBetweenX, Message: "must be non-negative"}
	}
	if .PaddingBetweenY < 0 {
		return &ConfigError{Field: "PaddingBetweenY", Value: .PaddingBetweenY, Message: "must be non-negative"}
	}
	if .GraphDirection != "LR" && .GraphDirection != "TD" {
		return &ConfigError{Field: "GraphDirection", Value: .GraphDirection, Message: "must be \"LR\" or \"TD\""}
	}
	if .StyleType != "cli" && .StyleType != "html" {
		return &ConfigError{Field: "StyleType", Value: .StyleType, Message: "must be \"cli\" or \"html\""}
	}

	// Validate sequence diagram configuration
	if .SequenceParticipantSpacing < 0 {
		return &ConfigError{Field: "SequenceParticipantSpacing", Value: .SequenceParticipantSpacing, Message: "must be non-negative"}
	}
	if .SequenceMessageSpacing < 0 {
		return &ConfigError{Field: "SequenceMessageSpacing", Value: .SequenceMessageSpacing, Message: "must be non-negative"}
	}
	if .SequenceSelfMessageWidth < 2 {
		return &ConfigError{Field: "SequenceSelfMessageWidth", Value: .SequenceSelfMessageWidth, Message: "must be at least 2"}
	}

	return nil
}

// ConfigError represents an invalid configuration value.
type ConfigError struct {
	Field   string
	Value   interface{}
	Message string
}

func ( *ConfigError) () string {
	return fmt.Sprintf("invalid config: %s = %v (%s)", .Field, .Value, .Message)
}